(function() {
	gaf.requires('gaf.services.GameService');
	
	/**
	 * The GameLoop class is the main loop for the game. It fires off an update event at an interval
	 * defined by the targetFPS property. Any object that needs to be updated at set intervals should
	 * subscribe to the gaf.services.GameService.Events.ON_UPDATE event.
	 **/
	gaf.define('gaf.services.GameLoop', gaf.services.GameService, {
	    /* -------------------------
		 * 	Properties
		 * ------------------------- */
		targetFPS: null,
		actualFPS: null,
	    /* -------------------------
		 * 	Constructor
		 * ------------------------- */
		constructor: function(game, targetFPS) {
			this.base(game);
			
			this.targetFPS = targetFPS;
		},
		start: function() {
			// Do some setup
			this.actualFPS = 0;
			this._previousFrameTime = new Date().getTime();
			this._frameCount = 0;
			
			// Start our loop and notify
			var that = this;
			this._timeout = setTimeout(function() { that.update(); }, (1000 / that.targetFPS));
			this.base();
		},
		stop: function() {
			this.actualFPS = 0;
			this._frameCount = 0;
			
			clearTimeout(this._timeout);
			delete this._timeout;
			
			// Notify
			this.base();
		},
		update: function() {
			// Notify of our event
			var event = new gaf.events.Event(gaf.services.GameLoop.Events.ON_UPDATE, this, {});
			this.notify(event);
			
			// Count frames
			var currentTime = new Date().getTime();
			var time = currentTime - this._previousFrameTime;
			if ( time >= 1000 ) {
				console.log('reset');
				this._frameCount = 0;
				this._previousFrameTime = currentTime;	
			} else {
				this._frameCount++;
			}
			this.actualFPS = this._frameCount;
			delete currentTime;
			
			// Trigger again
			var that = this;
			this._timeout = setTimeout(function() { that.update(); }, (1000 / that.targetFPS));
		},
	    /* -------------------------
		 * 	Static Properties
		 * ------------------------- */
		statics: {
			Events: {
				ON_UPDATE: 'onUpdate'
			}
		}
	});
})();
